package com.cyf.common.core.time;

import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author chenyifan
 * @create 2024-08-07 16:37
 */
public class DateUtil {

    public static final DateTimeFormatter defaultDateTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static final DateTimeFormatter defaultDateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    public static final DateTimeFormatter defaultTimeFormat = DateTimeFormatter.ofPattern("HH:mm:ss");
    public static final DateTimeFormatter MF = DateTimeFormatter.ofPattern("yyyy-MM");

    private static final String[] dateTimeFormatParts = {"y", "M", "d", "H", "m", "s", "S"};
    private static final String[] timeFormatParts = {"H", "m", "s", "S"};
    private static final String DATE_FORMAT_23 = "yyyyMMddHHmmssSSSSSSSSS";
    private static final String DATE_FORMAT_15 = "HHmmssSSSSSSSSS";

    /**
     * 选择日期格式
     * @param dateString 日期字符串
     * @return
     */
    private static DateTimeFormatter switchDateFormat(String dateString) {
        if (!StringUtils.hasLength(dateString)) {
            throw new IllegalArgumentException("时间字符串为空");
        }

        // 匹配多个数字，或者多个非数字字符
        Pattern pattern = Pattern.compile("(\\d+)|([^\\d]+)");
        Matcher matcher = pattern.matcher(dateString);
        List<String> numbers = new ArrayList<>();
        List<String> delimiters = new ArrayList<>();
        while (matcher.find()) {
            String group1 = matcher.group(1);
            String group2 = matcher.group(2);
            if (StringUtils.hasLength(group1)) {
                // 匹配到的是数字部分
                numbers.add(group1);
            } else if (StringUtils.hasLength(group2)) {
                // 匹配到的是非数字部分（即分隔符）
                delimiters.add(group2);
            }
        }

        // 如果分隔符为空，根据长度选择合适的格式
        int length = dateString.length();
        if (CollectionUtils.isEmpty(delimiters)) {
            String formatStr = length <= DATE_FORMAT_23.length() ? DATE_FORMAT_23.substring(0, length) : DATE_FORMAT_23;
            return DateTimeFormatter.ofPattern(formatStr);
        }

        StringBuilder formatStr = new StringBuilder();
        // 如果包含非数字字符，则构建自定义格式
        for (int i = 0; i < numbers.size() && i < dateTimeFormatParts.length; i++) {
            String number = numbers.get(i);
            for (int j = 0; j < number.length(); j++) {
                formatStr.append(dateTimeFormatParts[i]);
            }
            if (i < delimiters.size()) {
                formatStr.append(delimiters.get(i));
            }
        }

        if (formatStr.length() <= 0) {
            throw new IllegalArgumentException("未找到合适的日期格式");
        }

        return DateTimeFormatter.ofPattern(formatStr.toString());
    }

    /**
     * 选择时间格式
     * @param timeString 时间字符串
     * @return
     */
    private static DateTimeFormatter switchTimeFormat(String timeString) {
        if (!StringUtils.hasLength(timeString)) {
            throw new IllegalArgumentException("时间字符串为空");
        }

        // 匹配多个数字，或者多个非数字字符
        Pattern pattern = Pattern.compile("(\\d+)|([^\\d]+)");
        Matcher matcher = pattern.matcher(timeString);
        List<String> numbers = new ArrayList<>();
        List<String> delimiters = new ArrayList<>();
        while (matcher.find()) {
            String group1 = matcher.group(1);
            String group2 = matcher.group(2);
            if (StringUtils.hasLength(group1)) {
                // 匹配到的是数字部分
                numbers.add(group1);
            } else if (StringUtils.hasLength(group2)) {
                // 匹配到的是非数字部分（即分隔符）
                delimiters.add(group2);
            }
        }

        // 如果分隔符为空，根据长度选择合适的格式
        int length = timeString.length();
        if (CollectionUtils.isEmpty(delimiters)) {
            String formatStr = length <= DATE_FORMAT_15.length() ? DATE_FORMAT_15.substring(0, length) : DATE_FORMAT_15;
            return DateTimeFormatter.ofPattern(formatStr);
        }

        StringBuilder formatStr = new StringBuilder();
        // 如果包含非数字字符，则构建自定义格式
        for (int i = 0; i < numbers.size() && i < timeFormatParts.length; i++) {
            String number = numbers.get(i);
            for (int j = 0; j < number.length(); j++) {
                formatStr.append(timeFormatParts[i]);
            }
            if (i < delimiters.size()) {
                formatStr.append(delimiters.get(i));
            }
        }

        if (formatStr.length() <= 0) {
            throw new IllegalArgumentException("未找到合适的日期格式");
        }

        return DateTimeFormatter.ofPattern(formatStr.toString());
    }


    // ----------------------------------- 日期格式化 --------------------------------------------

    /**
     * 格式化日期时间为 yyyy-MM-dd HH:mm:ss 格式
     * @param time LocalDateTime
     * @return
     */
    public static String format(LocalDateTime time) {
        return time.format(defaultDateTimeFormat);
    }

    /**
     * 自定义时间格式方式
     * @param dateTime LocalDateTime
     * @param pattern 日期格式
     * @return
     */
    public static String format(LocalDateTime dateTime, String pattern) {
        return dateTime.format(DateTimeFormatter.ofPattern(pattern));
    }


    /**
     * 格式化日期时间为 yyyy-MM-dd 格式
     * @param time  LocalDate
     * @return
     */
    public static String format(LocalDate time) {
        return time.format(defaultDateFormat);
    }

    /**
     * 自定义日期格式方式
     * @param date LocalDate
     * @param pattern 日期格式
     * @return
     */
    public static String format(LocalDate date, String pattern) {
        return date.format(DateTimeFormatter.ofPattern(pattern));
    }


    /**
     * 格式化日期时间为 HH:mm:ss 格式
     * @param time LocalTime
     * @return
     */
    public static String format(LocalTime time) {
        return time.format(defaultTimeFormat);
    }

    /**
     * 自定义时间格式方式
     * @param time LocalTime
     * @param pattern 日期格式
     * @return
     */
    public static String format(LocalTime time, String pattern) {
        return time.format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 格式化日期时间为 yyyy-MM 格式
     * @param time
     * @return
     */
    public static String format(YearMonth time) {
        return time.format(MF);
    }

    /**
     * 自定义年月格式方式
     * @param time
     * @param pattern
     * @return
     */

    public static String format(YearMonth time, String pattern) {
        return time.format(DateTimeFormatter.ofPattern(pattern));
    }

    public static List<String> formatDateTimeList(Collection<LocalDateTime> timeList) {
        return timeList.stream().map(DateUtil::format).collect(Collectors.toList());
    }

    public static List<String> formatDateList(Collection<LocalDate> timeList) {
        return timeList.stream().map(DateUtil::format).collect(Collectors.toList());
    }

    // -------------------------------- 日期字符串解析 -------------------------------------------

    /**
     * 解析日期字符串为 LocalDateTime
     * @param time 时间字符串
     * @return
     */
    public static LocalDateTime parseDateTime(String time) {
        // 先尝试使用默认格式解析
        try {
            return LocalDateTime.parse(time, defaultDateTimeFormat);
        } catch (Exception ignored) {
        }

        DateTimeFormatter formatter = switchDateFormat(time);
        try {
            return LocalDateTime.parse(time, formatter);
        } catch (Exception e) {
            return LocalDate.parse(time, formatter).atTime(LocalTime.MIN);
        }
    }

    /**
     * 自定义时间解析方式
     * @param time 时间字符串
     * @param pattern 日期格式
     * @return
     */
    public static LocalDateTime parseDateTime(String time, String pattern) {
        return LocalDateTime.parse(time, DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 解析日期字符串为 LocalDate
     * @param time 时间字符串
     * @return
     */
    public static LocalDate parseDate(String time) {
        try {
            return LocalDate.parse(time, defaultDateFormat);
        } catch (Exception ignored) {
        }

        DateTimeFormatter formatter = switchDateFormat(time);
        try {
            return LocalDate.parse(time, formatter);
        } catch (Exception e) {
            return LocalDateTime.parse(time, formatter).toLocalDate();
        }
    }

    /**
     * 自定义日期解析方式
     * @param time 时间字符串
     * @param pattern 日期格式化器
     * @return
     */
    public static LocalDate parseDate(String time, String pattern) {
        return LocalDate.parse(time, DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 解析日期字符串为 LocalTime
     * @param time 时间字符串
     * @return
     */
    public static LocalTime parseTime(String time) {
        try {
            return LocalTime.parse(time, defaultTimeFormat);
        } catch (Exception ignored) {
        }

        return LocalTime.parse(time, switchTimeFormat(time));
    }

    /**
     * 自定义日期解析方式
     * @param time 时间字符串
     * @param pattern 日期格式化器
     * @return
     */
    public static LocalTime parseTime(String time, String pattern) {
        return LocalTime.parse(time, DateTimeFormatter.ofPattern(pattern));
    }

    public static YearMonth parseYearMonth(String time) {
        return YearMonth.parse(time, MF);
    }

    public static YearMonth parseYearMonth(String time, String pattern) {
        return YearMonth.parse(time, DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 解析日期字符串为 LocalDateTime
     * @param times 时间字符串列表
     * @return
     */
    public static List<LocalDateTime> parseDateTimeList(Collection<String> times) {
        return times.stream().map(DateUtil::parseDateTime).collect(Collectors.toList());
    }

    /**
     * 解析日期字符串为 LocalDate
     * @param times 时间字符串列表
     * @return
     */
    public static List<LocalDate> parseDateList(Collection<String> times) {
        return times.stream().map(DateUtil::parseDate).collect(Collectors.toList());
    }


    // ------------------------------- 时间列表获取 ----------------------------------------

    /**
     * 从给定的开始时间到结束时间之间生成一个包含每个小时时间戳的列表，
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     */
    public static List<LocalDateTime> getHourList(LocalDateTime startTime, LocalDateTime endTime) {
        List<LocalDateTime> timeList = new ArrayList<>();
        startTime = startTime.truncatedTo(ChronoUnit.HOURS);
        while (!startTime.isAfter(endTime)) {
            timeList.add(startTime);
            startTime = startTime.plusHours(1);
        }
        return timeList;
    }

    /**
     * 从给定的开始时间到结束时间之间生成一个包含每个日期的列表
     * @param startTime 开始时间
     * @param endTime 结束时间

     * @return
     */
    public static List<LocalDate> getDateList(LocalDate startTime, LocalDate endTime) {
        List<LocalDate> timeList = new ArrayList<>();
        while (!startTime.isAfter(endTime)) {
            timeList.add(startTime);
            startTime = startTime.plusDays(1);
        }
        return timeList;
    }


    /**
     * 从给定的开始时间到结束时间之间生成一个包含每周开始时间的列表
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     */
    public static List<LocalDate> getWeekList(LocalDate startTime, LocalDate endTime) {
        List<LocalDate> timeList = new ArrayList<>();
        startTime = getWeekStart(startTime);
        while (startTime.compareTo(endTime) <= 0) {
            timeList.add(startTime);
            startTime = startTime.plusDays(7);
        }
        return timeList;
    }


    // ------------------------------------- 时间比较 ---------------------------

    /**
     * 比较两个 LocalDateTime 对象是否在同一天且小时数相同
     * @param time1 时间1
     * @param time2 时间2
     * @return
     */
    public static boolean eqDayAndHour(LocalDateTime time1, LocalDateTime time2) {
        return Objects.equals(time1.truncatedTo(ChronoUnit.HOURS), time2.truncatedTo(ChronoUnit.HOURS));
    }


    /**
     * 比较两个 LocalDateTime 对象是否在同一天且小时分钟数相同
     * @param time1 时间1
     * @param time2 时间2
     * @return
     */
    public static boolean eqDayAndHourMin(LocalDateTime time1, LocalDateTime time2) {
        // truncatedTo：截断时间
        return Objects.equals(time1.truncatedTo(ChronoUnit.MINUTES), time2.truncatedTo(ChronoUnit.MINUTES));
    }


    // ------------------------------ 年，月，日，小时，开始和结束时间获取 -------------------

    /**
     * 小时的开始时间
     * @param time LocalDateTime
     * @return
     */
    public static LocalDateTime getHourStart(LocalDateTime time) {
        return time.truncatedTo(ChronoUnit.HOURS);
    }

    /**
     * 小时的结束时间
     * @param time LocalDateTime
     * @return
     */
    public static LocalDateTime getHourEnd(LocalDateTime time) {
        return time.toLocalDate().atTime(time.getHour(), 59, 59);
    }

    /**
     * 每天的开始时间
     * @param time LocalDateTime
     * @return
     */
    public static LocalDateTime getDayStart(LocalDateTime time) {
        return time.truncatedTo(ChronoUnit.DAYS);
    }

    /**
     * 每天的结束时间
     * @param time LocalDateTime
     * @return
     */
    public static LocalDateTime getDayEnd(LocalDateTime time) {
        return time.toLocalDate().atTime(23, 59, 59);
    }

    /**
     * 一个月的第一天
     * @param time LocalDate
     * @return
     */
    public static LocalDate getMonthStart(LocalDate time) {
        return time.with(TemporalAdjusters.firstDayOfMonth());
    }

    /**
     * 一个月的最后一天
     * @param date LocalDate
     * @return
     */
    public static LocalDate getMonthEnd(LocalDate date) {
        return date.with(TemporalAdjusters.lastDayOfMonth());
    }


    /**
     * 获取该季度的第一天
     * @param time LocalDate
     * @return
     */
    public static LocalDate getSeasonStart(LocalDate time) {
        int month = time.getMonthValue();
        int season = month % 3 == 0 ? month / 3 : month / 3 + 1;
        return LocalDate.of(time.getYear(), season * 3 - 2, 1);
    }


    /**
     * 获取该季度的最后一天
     * @param time LocalDate
     * @return
     */
    public static LocalDate getSeasonEnd(LocalDate time) {
        int month = time.getMonthValue();
        if (month <= 3) {
            return LocalDate.of(time.getYear(), 3, 31);
        } else if (month <= 6) {
            return LocalDate.of(time.getYear(), 6, 30);
        } else if (month <= 9) {
            return LocalDate.of(time.getYear(), 9, 30);
        } else {
            return LocalDate.of(time.getYear(), 12, 31);
        }
    }

    /**
     * 获取一周开始时间
     * @param date
     * @return
     */
    public static LocalDate getWeekStart(LocalDate date) {
        return date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
    }

    /**
     * 获取一周结束
     * @param date
     * @return
     */
    public static LocalDate getWeekEnd(LocalDate date) {
        return date.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
    }


    // ---------------------------- 两个时间之间的差值 ----------------------------------------

    /**
     * 获取两个时间的差值，如果结束时间早于开始时间，获取结果为负。
     * @param startTimeInclude 开始时间（包含）
     * @param endTimeExclude 结束时间（不包含）
     * @return
     */
    public static Duration diff(Temporal startTimeInclude, Temporal endTimeExclude) {
        return Duration.between(startTimeInclude, endTimeExclude);
    }


    // ---------------------------------- 其他方法 ------------------------------------------------

    /**
     * 求补集，属于全集但不属于集合A，以小时为判断标准
     * @param all 全集
     * @param collA 集合A
     * @return
     */
    public static List<LocalDateTime> diffHourList(Collection<LocalDateTime> all, Collection<LocalDateTime> collA) {
        List<LocalDateTime> list1 = all.stream().map(ele -> ele.truncatedTo(ChronoUnit.HOURS)).collect(Collectors.toList());
        List<LocalDateTime> list2 = collA.stream().map(ele -> ele.truncatedTo(ChronoUnit.HOURS)).collect(Collectors.toList());
        return list1.stream().filter(ele -> !list2.contains(ele)).collect(Collectors.toList());
    }

    /**
     * 求补集，属于全集但不属于集合A，以小时为判断标准
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param collA 集合A
     * @return
     */
    public static List<LocalDateTime> diffHourList(LocalDateTime startTime, LocalDateTime endTime, List<LocalDateTime> collA) {
        List<LocalDateTime> hourList = getHourList(startTime, endTime);
        return diffHourList(hourList, collA);
    }

    /**
     * 时间戳转LocalDateTime
     * @param timestamp 时间戳
     * @return
     */
    public static LocalDateTime timestampToLocalDateTime(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    /**
     * Date 转 LocalDateTime
     * @param date
     * @return
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        Instant instant = date.toInstant();
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    public static List<String> getTimeList(String startTime, String endTime, String timeType, boolean isShort) {
        List<String> timeList = new ArrayList<>();
        if ("year".equalsIgnoreCase(timeType)) {
            int startYear = Integer.parseInt(startTime.substring(0, 4));
            int endYear = Integer.parseInt(endTime.substring(0, 4));
            if (isShort) {
                for (int i = startYear; i <= endYear; i++) {
                    timeList.add(String.valueOf(i));
                }
            } else {
                for (int i = startYear; i <= endYear; i++) {
                    timeList.add(i + "-01-01 00:00:00");
                }
            }
        } else if ("season".equalsIgnoreCase(timeType)) {
            int startMonth = Integer.parseInt(startTime.substring(5, 7));
            int startSeason = startMonth % 3 == 0 ? startMonth / 3 : startMonth / 3 + 1;
            int endMonth = Integer.parseInt(endTime.substring(5, 7));
            int endSeason = endMonth % 3 == 0 ? endMonth / 3 : endMonth / 3 + 1;
            YearMonth start = YearMonth.of(Integer.parseInt(startTime.substring(0, 4)), startSeason * 3 - 2);
            YearMonth end = YearMonth.of(Integer.parseInt(endTime.substring(0, 4)), endSeason * 3 - 2);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(isShort ? "yyyy-MM" : "yyyy-MM-01 00:00:00");
            while (!start.isAfter(end)) {
                timeList.add(start.format(formatter));
                start = start.plusMonths(3);
            }
        } else if ("month".equalsIgnoreCase(timeType)) {
            YearMonth start = YearMonth.of(Integer.parseInt(startTime.substring(0, 4)), Integer.parseInt(startTime.substring(5, 7)));
            YearMonth end = YearMonth.of(Integer.parseInt(endTime.substring(0, 4)), Integer.parseInt(endTime.substring(5, 7)));
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(isShort ? "yyyy-MM" : "yyyy-MM-01 00:00:00");
            while (!start.isAfter(end)) {
                timeList.add(start.format(formatter));
                start = start.plusMonths(1);
            }
        } else if ("day".equalsIgnoreCase(timeType)) {
            DateTimeFormatter shortFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate start = LocalDate.parse(startTime.substring(0, 10), shortFormatter);
            LocalDate end = LocalDate.parse(endTime.substring(0, 10), shortFormatter);
            DateTimeFormatter formatter = isShort ? shortFormatter : DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
            while (!start.isAfter(end)) {
                timeList.add(start.format(formatter));
                start = start.plusDays(1);
            }
        } else if ("hour".equalsIgnoreCase(timeType)) {
            DateTimeFormatter shortFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");
            LocalDateTime start = LocalDateTime.parse(startTime.substring(0, 13), shortFormatter);
            LocalDateTime end = LocalDateTime.parse(endTime.substring(0, 13), shortFormatter);
            DateTimeFormatter formatter = isShort ? shortFormatter : DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00:00");
            while (!start.isAfter(end)) {
                timeList.add(start.format(formatter));
                start = start.plusHours(1);
            }
        } else if ("min".equalsIgnoreCase(timeType)) {
            DateTimeFormatter shortFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
            LocalDateTime start = LocalDateTime.parse(startTime.substring(0, 16), shortFormatter);
            LocalDateTime end = LocalDateTime.parse(endTime.substring(0, 16), shortFormatter);
            DateTimeFormatter formatter = isShort ? shortFormatter : DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:00");
            while (!start.isAfter(end)) {
                timeList.add(start.format(formatter));
                start = start.plusMinutes(1);
            }
        } else {
            throw new IllegalArgumentException("Unknown timeType: " + timeType);
        }
        return timeList;
    }

    public static String getShortTime(String time, String timeType) {
        if ("year".equalsIgnoreCase(timeType)) {
            return time.substring(0, 4);
        } else if ("season".equalsIgnoreCase(timeType)) {
            int month = Integer.parseInt(time.substring(5, 7));
            if (month <= 3) {
                return time.substring(0, 4) + "-01";
            } else if (month <= 6) {
                return time.substring(0, 4) + "-04";
            } else if (month <= 9) {
                return time.substring(0, 4) + "-07";
            } else {
                return time.substring(0, 4) + "-10";
            }
        } else if ("month".equalsIgnoreCase(timeType)) {
            return time.substring(0, 7);
        } else if ("day".equalsIgnoreCase(timeType)) {
            return time.substring(0, 10);
        } else if ("hour".equalsIgnoreCase(timeType)) {
            return time.substring(0, 13);
        } else if ("min".equalsIgnoreCase(timeType)) {
            return time.substring(0, 16);
        }
        throw new IllegalArgumentException("Unknown timeType: " + timeType);
    }

    public static String getEndTime(String time, String timeType) {
        if ("year".equalsIgnoreCase(timeType)) {
            return time.substring(0, 4) + "-12-31 23:59:59";
        } else if ("season".equalsIgnoreCase(timeType)) {
            int month = Integer.parseInt(time.substring(5, 7));
            if (month <= 3) {
                return time.substring(0, 4) + "-03-31 23:59:59";
            } else if (month <= 6) {
                return time.substring(0, 4) + "-06-30 23:59:59";
            } else if (month <= 9) {
                return time.substring(0, 4) + "-09-30 23:59:59";
            } else {
                return time.substring(0, 4) + "-12-31 23:59:59";
            }
        } else if ("month".equalsIgnoreCase(timeType)) {
            int day = YearMonth.of(Integer.parseInt(time.substring(0, 4)), Integer.parseInt(time.substring(5, 7))).lengthOfMonth();
            return time.substring(0, 7) + "-" + day + " 23:59:59";
        } else if ("day".equalsIgnoreCase(timeType)) {
            return time.substring(0, 10) + " 23:59:59";
        } else if ("hour".equalsIgnoreCase(timeType)) {
            return time.substring(0, 13) + ":59:59";
        } else if ("min".equalsIgnoreCase(timeType)) {
            return time.substring(0, 16) + ":59";
        }
        throw new IllegalArgumentException("Unknown timeType: " + timeType);
    }

    public static String getStartTime(String time, String timeType) {
        if ("year".equalsIgnoreCase(timeType)) {
            return time.substring(0, 4) + "-01-01 00:00:00";
        } else if ("season".equalsIgnoreCase(timeType)) {
            int month = Integer.parseInt(time.substring(5, 7));
            if (month <= 3) {
                return time.substring(0, 4) + "-01-01 00:00:00";
            } else if (month <= 6) {
                return time.substring(0, 4) + "-04-01 00:00:00";
            } else if (month <= 9) {
                return time.substring(0, 4) + "-07-01 00:00:00";
            } else {
                return time.substring(0, 4) + "-10-01 00:00:00";
            }
        } else if ("month".equalsIgnoreCase(timeType)) {
            return time.substring(0, 7) + "-01 00:00:00";
        } else if ("day".equalsIgnoreCase(timeType)) {
            return time.substring(0, 10) + " 00:00:00";
        } else if ("hour".equalsIgnoreCase(timeType)) {
            return time.substring(0, 13) + ":00:00";
        } else if ("min".equalsIgnoreCase(timeType)) {
            return time.substring(0, 16) + ":00";
        }
        throw new IllegalArgumentException("Unknown timeType: " + timeType);
    }

    /**
     * 获取当前时间所在的月份有多少周
     * @param date
     * @return
     */
    public static int getMonthWeekCount(LocalDate date) {
        LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth());
        WeekFields weekFields = WeekFields.of(Locale.getDefault());
        return lastDay.get(weekFields.weekOfMonth());
    }

    /**
     * 获取当前时间所在的周是该月的第几周
     * @param date
     * @return
     */
    public static int getWeekOfMonth(LocalDate date) {
        WeekFields weekFields = WeekFields.of(Locale.getDefault());
        return date.get(weekFields.weekOfMonth());
    }

    /**
     * 基于增长天数，获取时间范围列表
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @param plusDays 增长天数
     * @return
     */
    public static List<List<String>> getDateRangeByPlusDays(String startDate, String endDate, int plusDays) {
        LocalDate start = parseDate(startDate);
        LocalDate end = parseDate(endDate);
        List<List<String>> rangeList = new ArrayList<>();
        while (!start.isAfter(end)) {
            if (start.plusDays(plusDays).isAfter(end)) {
                rangeList.add(Arrays.asList(format(start), format(end)));
                break;
            } else {
                rangeList.add(Arrays.asList(format(start), format(start.plusDays(plusDays))));
            }
            start = start.plusDays(plusDays + 1);
        }
        return rangeList;
    }
}